#pragma once
#include <stdint.h>
#include "common/luajit-header.h"

#ifdef __cplusplus

// void luaL_open_console_extra (lua_State *L);
void luaL_register_ext (lua_State *L, const luaL_Reg *l);
void luaL_set_aliases (lua_State *L, const char** str_list);
void luaL_va_optints (lua_State *L, int start, int value, ...);
void luaL_va_optints (lua_State *L, int start, int** args, int* value);
int luaL_va_setfield_ints (lua_State *L, const void* _t);
void luaL_va_tointegers (lua_State *L, int start, ...);

int luastr_escape (lua_State * l);
int luastr_unescape (lua_State * l);
int luastr_align (lua_State * l);

void luaopen_con_int32_api_ (lua_State*);

void swap_int(int & a , int & b);
unsigned char bit_reverse (unsigned char x);
#endif

#define luaL_ref_reg(L) luaL_ref(L, LUA_REGISTRYINDEX)
#define luaL_unref_reg(L, i) luaL_unref(L, LUA_REGISTRYINDEX, i)

#define clamp_int8(x) if(x<0)x=0;if(x>255)x=255;

// compatible to legacy luaL_getn function
#if LUA_VERSION_NUM >= 502
# define luaL_getn(L, i)	lua_rawlen(L, (i))
#elif LUA_VERSION_NUM >= 501 && !defined(luaL_getn)
# define luaL_getn(L, i)	lua_objlen(L, (i))
#endif

// checks X86 architecture
#if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
# define X86
# define X86_64
# define __REG_A "rax"
# define __REG_B "rbx"
# define __REG_C "rcx"
# define __REG_D "rdx"
# define __REG_SP "rsp"
# define __REG_FP "rbp"
# define __REG_SI "rsi"
# define __REG_DI "rdi"
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
# define X86
# define __REG_A "eax"
# define __REG_B "ebx"
# define __REG_C "ecx"
# define __REG_D "edx"
# define __REG_SP "esp"
# define __REG_FP "ebp"
# define __REG_SI "esi"
# define __REG_DI "edi"
#endif

#ifdef _MSC_VER
unsigned msvc_ctz(unsigned a);
unsigned msvc_clz(unsigned a);

#define __builtin_ctz msvc_ctz
#define __builtin_clz msvc_clz
#endif

#define MTOS_EXPAND(str) #str
#define MTOS(str) MTOS_EXPAND(str)

#if defined(_SDL) && __cplusplus
// SDL must be installed in luaconsole_SDL
#define CHRW	8
#define CHRH 	16
#define XCHRS	80
#define YCHRS	25
#define XRES	(CHRW * XCHRS)
#define YRES	(CHRH * YCHRS)
#define SSKIP	12
#define USE_FASM	

typedef uint8_t BLINK_FLAGS_TYPE;

#define IN_CONSOLE(x, y) ((x) >= 0 && (y) >= 0 && (x) < (XCHRS) && (y) < (YCHRS))

struct _MY_HANDLE_STATUS {
	void*	h;	// HANDLE
	int	status;
};

extern int input_chars, input_pos, curr_fg, curr_bg, first_input_line;
extern char *input_buffer, *input_buffer2;
extern void *MainThreadHandle;
extern _MY_HANDLE_STATUS ScriptThreadHandle;

#define REG_MAX_LUA_STATES 20
extern intptr_t luacon_stateRegTable[2 * REG_MAX_LUA_STATES];
extern int luacon_tls_idx;

void drawchr (int32_t* buf, int x, int y, int c);
void scroll_dn (int32_t* buf, int lines);
void clear_line (int32_t* buf, int line_n, int lines = 1);

lua_State * luacon_regnewstate();
void luacon_reg_clearupmem(lua_State*);

#endif
